package com.peak.distribution.web.order;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.peak.distribution.entity.agent.DisAgent;
import com.peak.distribution.entity.order.DisOrder;
import com.peak.distribution.enums.OrderStatus;
import com.peak.distribution.exception.DistributionError;
import com.peak.distribution.exception.DistributionException;
import com.peak.distribution.manager.order.DisOrderManager;
import com.peak.distribution.service.agent.DisAgentService;
import com.peak.distribution.service.order.DisOrderService;
import com.peak.distribution.vo.order.DisOrderGoodsVo;
import com.peak.distribution.vo.order.DisOrderVo;
import com.peak.distribution.web.validator.Valid;
import com.peak.distribution.web.validator.ValidateRule;
import com.peak.distribution.web.validator.ValidateRuleBuilder;
import com.peak.distribution.web.validator.Validation;
import com.peak.distribution.web.validator.method.Require;
import com.peak.spring.boot.api.repository.FilterParam;
import com.peak.spring.boot.api.repository.FilterParam.Operator;
import com.peak.spring.boot.api.web.JsonMessage;
import com.peak.spring.boot.api.web.JsonPage;
import com.peak.spring.boot.builder.repository.FilterParamBuilder;
import com.peak.spring.boot.builder.web.JsonBuilder;
import com.peak.spring.boot.core.mapper.BeanMapper;
import com.peak.spring.boot.core.web.BaseController;
import com.peak.spring.boot.tools.Converts;
import com.peak.spring.boot.tools.Emptys;
import com.peak.spring.boot.tools.Servlets;

@RestController
@RequestMapping("/order")
public class DisOrderController extends BaseController<DisOrder, DisOrderVo> {
	
	@Autowired
	private DisOrderService orderSerivce;
	
	@Autowired
	private DisOrderManager orderManager;
	
	@Autowired
	private DisAgentService agentService;
	
	@PostMapping("/list")
	public JsonPage list(HttpServletRequest request) {
		JsonPage json = listOrder(request);
		return json;
	}
	
	@PostMapping("/my/list")
	public JsonPage myList(HttpServletRequest request) {
		JsonPage json = listOrder(request, new FilterParam("agent.id", Operator.EQ, agentService.getCurrentAgentId()));
		return json;
	}

	private JsonPage listOrder(HttpServletRequest request, FilterParam... params) {
		FilterParamBuilder builder = FilterParamBuilder.create().parseRequest(request);
		List<FilterParam> filterParams = builder.filters();
		if (Emptys.isNotEmpty(params)) {
			filterParams.addAll(Arrays.asList(params));
		}
		PageRequest pageRequest = builder.pageRequest();
		beforeList(request, filterParams, pageRequest);
		Page<DisOrder> page = baseManager.findPage(filterParams, pageRequest);
		// 把goods的转换实现了
		Page<Map<String, Object>> voPage = page.map(new Converter<DisOrder, Map<String, Object>>() {

			@Override
			public Map<String, Object> convert(DisOrder source) {
				Map<String, Object> vo = BeanMapper.map(source, DisOrderVo.class);
				List<Map<String, Object>> goodsVos  = source.getGoodses().stream().map(p -> BeanMapper.map(p, DisOrderGoodsVo.class)).collect(Collectors.toList());
				vo.put("goodses", goodsVos);
				return vo;
			}
		});
		JsonPage json = JsonBuilder.page().success().page(voPage).build();
		json = afterList(json);
		return json;
	}

	
	@PostMapping("/my/count")
	public JsonMessage count(HttpServletRequest request) {
		Map<String, Integer> map = orderManager.countOrderByStatus( agentService.getCurrentAgentId());
		return JsonBuilder.message().success().content(map).build();
	}
	
	@PostMapping("/count")
	public JsonMessage countOrder(HttpServletRequest request) {
		Map<String, Integer> map = orderManager.countOrderByStatus(OrderStatus.UNPAID, OrderStatus.DELIVERING);
		return JsonBuilder.message().success().content(map).build();
	}

	@PostMapping("/add")
	public JsonMessage add(@RequestBody Map<String, String> request) {
		DisAgent agent = agentService.getCurrentAgent();
		if (!agent.getAuditStatus()) {
			throw new DistributionException(DistributionError.AGENT_NOT_AUDIT);
		}
		String json = request.get("carts");
		if (Emptys.isEmpty(json)) {
			throw new DistributionException(DistributionError.CART_ADD_EMPTY);
		}
		Integer receiverId = Converts.toInteger(request.get("receiverId"));
		String payType = request.get("payChannel");
		String remark = request.get("remark");
		DisOrder order = orderSerivce.add(json, receiverId, payType, remark);
		return JsonBuilder.message().success().content(order).convert(DisOrderVo.class).build();
	}
	
	@PostMapping("/my/cancel/{id}")
	public JsonMessage cancel(@PathVariable("id") Integer id, HttpServletRequest request) {
		DisAgent agent = agentService.getCurrentAgent();
		orderSerivce.cancel(agent, id);
		return JsonBuilder.message().success().build();
	}
	
	@PostMapping("/confirm/paid/{id}")
	public JsonMessage confirmPaid(@PathVariable("id") Integer id, HttpServletRequest request) {
		orderSerivce.confirmPaid(id);
		return JsonBuilder.message().success().build();
	}
	
	@PostMapping("/shipping/{id}")
	public JsonMessage shipping(@PathVariable("id") Integer id, HttpServletRequest request) {
		Map<String, Object> map = Servlets.getParametersStartingWith(request, "");
		List<ValidateRule> rules = ValidateRuleBuilder.create()
				.rule("express", "快递公司").methods(Require.class)
				.and()
				.rule("waybillNo", "运单号").methods(Require.class)
				.build();
		Valid valid = Validation.buildDefaultValidatorFactory().rule(rules).validate(map);
		if (valid.isValid()) {
			String express = Converts.toString(map.get("express"));
			String waybillNo = Converts.toString(map.get("waybillNo"));
			orderSerivce.shipping(id, express, waybillNo);
			return JsonBuilder.message().success().build();
		} else {
			return JsonBuilder.message().fail().content(valid.getErrorMessages()).build();
		}
		
	}
	
	@PostMapping("/calculate/shipping/fee")
	public JsonMessage calculateShippingFee(HttpServletRequest request) {
		Map<String, Object> map = Servlets.getParametersStartingWith(request, "");
		int goodsFee = Converts.toInt(Converts.toDouble(map.get("goodsFee")) * 100);
		return JsonBuilder.message().success().content(orderSerivce.calculateShippingFee(goodsFee)).build();
	}
}
